<--- %%NOBANNER%% --> _rantbl_.sas
 BackForward

/*-------------------<-- Start of Description -->--------------------\
| Generate random variate from a tabled probability distribution;    |
| The functio utilize the SAS function rantbl;                       |
|--------------------<--- End of Description -->---------------------|
|--------------------------------------------------------------------|
|--------------<--- Start of Files or Arguments Needed -->-----------|
| Arguments Need:                                                    |
|      seed  - seed; Required, default is the current system time;   |
|      var   - the variable to save the generated random variates;   |
|      p     - the proportion variables;                             |
|      Note: 1) if p is an array, it must be entered as "of p{*}";   |
|               if p is just a bunch of proportions, it must be      |
|               entered as "of p1 - p9" for example;                 |
|            2) the above "of" can be omitted;                       |  
|      lower - the lower bound;                                      |
|      temp - the seed value saver;                                  |
|      temp - a variable for internal use only;                      |
|---------------<--- End of Files or Arguments Needed -->------------|
|--------------------------------------------------------------------|
|----------------<--- Start of Example and Usage -->-----------------|
| Example                                                            |
|   data one;                                                        |
|      array _p(3) (0.25, 0.5, 0.25);                                |
|      %_rantbl_(seed=1, var=x, p=of _p{*});                         |
|      put x _rantbl0_;                                              |
|      do i=1 to 100000;                                             |
|         x=%_rantbl_(seed=_rantbl0_, p=of _p{*});                   |
|         output;                                                    |
|      end;                                                          |
|   run;                                                             |
|   %print(one(obs=200));                                            |
| Usage: _rantbl_(seed=%sysfunc(datetime(), 15.), var=REQUIRED, p=,  |
|               lower=, temp=_rantbl0_);                             |
\-------------------<--- End of Example and Usage -->---------------*/
%macro _rantbl_(seed=%sysfunc(datetime(), 15.), var=, p=, lower=, 
               temp=_rantbl0_);
/*--------------------------------------------\
| Author:  Duo Zhou;                          |
| Created: 3-22-2002 6:30pm;                  |
| Purpose: Generate random variates from a    |
|          tabled probability distribution;   |
\--------------------------------------------*/
%if (%quote(&seed) eq) or (%quote(&p) eq) %then %do;
   %if (%quote(&seed) eq) %then %do;
      %put ==> Error: This is not a valid seed!; 
      %if (%length(&var)) %then %do; &var=.; %end;
      %else %do; .;%end;
   %end;
   %if (%quote(&p) eq) %then %do;
      %put ==> Error: I need a valid proportion or proportion array!; 
      %if (%length(&var)) %then %do; &var=.; %end;
      %else %do; .;%end;
   %end;
   %goto finish;
%end;
%else %do; 
   %if (%length(&var)) %then %do;
       %if (not %sysfunc(rxmatch(%sysfunc(rxparse(.|$a|$A|$w)),&seed))) %then %do;
           drop &temp;
           retain &temp &seed;
            %let seed=&temp; 
       %end;
       %if (%length(&p) ge 2) %then %do;
          %if (%quote(%substr(%left(%upcase(&p)),1,2))) ne %quote(OF) %then %do;
             call rantbl(&seed, of &p, &var);
          %end;
          %else %do;
             call rantbl(&seed, &p, &var);
          %end;
       %end;
       %else %do;
          call rantbl(&seed, &p, &var);
       %end;
       %if (%length(&lower)) %then &var=&var;
   %end;
   %else %do;
      %if (%length(&p) ge 2) %then %do;
         %if (%quote(%substr(%left(%upcase(&p)),1,2))) ne %quote(OF) %then %do;
            rantbl(&seed, of &p);
         %end;
         %else %do;
            rantbl(&seed, &p);
         %end;
      %end;
      %else %do;
         rantbl(&seed, &p);
      %end;
   %end;
   %if (%length(&lower)) %then +&lower-1;
%end;
%finish:
%mend _rantbl_;